<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="laravel-pulse" tabindex="-1"><a class="header-anchor" href="#laravel-pulse"><span>Laravel Pulse</span></a></h2>
<ul>
<li><a href="#introduction">介绍</a></li>
<li><a href="#installation">安装</a>
<ul>
<li><a href="#configuration">配置</a></li>
</ul>
</li>
<li><a href="#dashboard">仪表板</a>
<ul>
<li><a href="#dashboard-authorization">授权</a></li>
<li><a href="#dashboard-customization">自定义</a></li>
<li><a href="#dashboard-resolving-users">解决用户</a></li>
<li><a href="#dashboard-cards">卡片</a></li>
</ul>
</li>
<li><a href="#capturing-entries">记录条目</a>
<ul>
<li><a href="#recorders">记录器</a></li>
<li><a href="#filtering">过滤</a></li>
</ul>
</li>
<li><a href="#performance">性能</a>
<ul>
<li><a href="#using-a-different-database">使用不同数据库</a></li>
<li><a href="#ingest">Redis 导入</a></li>
<li><a href="#sampling">抽样</a></li>
<li><a href="#trimming">修剪</a></li>
<li><a href="#pulse-exceptions">处理 Pulse 异常</a></li>
</ul>
</li>
<li><a href="#custom-cards">自定义卡片</a>
<ul>
<li><a href="#custom-card-components">卡片组件</a></li>
<li><a href="#custom-card-styling">样式</a></li>
<li><a href="#custom-card-data">数据捕获和聚合</a></li>
</ul>
</li>
</ul>
<h2 id="介绍" tabindex="-1"><a class="header-anchor" href="#介绍"><span>介绍</span></a></h2>
<p><a href="https://github.com/laravel/pulse" target="_blank" rel="noopener noreferrer">Laravel Pulse</a> 提供了应用程序性能和使用情况的一览洞察。通过 Pulse，你可以追踪诸如慢作业和端点、找到最活跃的用户等瓶颈问题。</p>
<p>要深入调试单个事件，请查看 <a href="https://learnku.com/docs/laravel/11.x/telescope" target="_blank" rel="noopener noreferrer">Laravel Telescope</a>。</p>
<h2 id="安装" tabindex="-1"><a class="header-anchor" href="#安装"><span>安装</span></a></h2>
<blockquote>
<p><strong>注意</strong><br>
Pulse 的官方存储实现目前需要 MySQL、MariaDB 或 PostgreSQL 数据库。如果你使用不同的数据库引擎，你将需要一个单独的 MySQL、MariaDB 或 PostgreSQL 数据库来存储 Pulse 数据。</p>
</blockquote>
<p>你可以使用 Composer 包管理器安装 Pulse：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> require laravel/pulse</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>接下来，你应该使用 <code v-pre>vendor:publish</code> Artisan 命令发布 Pulse 配置和迁移文件：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan vendor:publish <span class="token parameter variable">--provider</span><span class="token operator">=</span><span class="token string">"Laravel\Pulse\PulseServiceProvider"</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>最后，你应该运行 <code v-pre>migrate</code> 命令来创建存储 Pulse 数据所需的表：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan migrate</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>一旦运行了 Pulse 的数据库迁移，你可以通过 <code v-pre>/pulse</code> 路由访问 Pulse 仪表板。</p>
<blockquote>
<p><strong>注意</strong><br>
如果你不想将 Pulse 数据存储在应用程序的主数据库中，你可以<a href="#using-a-different-database">指定一个专用的数据库连接</a>。</p>
</blockquote>
<h3 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h3>
<p>许多 Pulse 的配置选项可以使用环境变量进行控制。要查看可用选项、注册新的记录器或配置高级选项，你可以发布 <code v-pre>config/pulse.php</code> 配置文件：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan vendor:publish <span class="token parameter variable">--tag</span><span class="token operator">=</span>pulse-config</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="仪表板" tabindex="-1"><a class="header-anchor" href="#仪表板"><span>仪表板</span></a></h2>
<h3 id="授权" tabindex="-1"><a class="header-anchor" href="#授权"><span>授权</span></a></h3>
<p>可以通过 <code v-pre>/pulse</code> 路由访问 Pulse 仪表板。默认情况下，你只能在 <code v-pre>local</code> 环境中访问此仪表板，因此你需要为生产环境配置授权，通过自定义 <code v-pre>'viewPulse'</code> 授权门来实现。你可以在应用程序的 <code v-pre>app/Providers/AppServiceProvider.php</code> 文件中完成这个操作：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Gate</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Bootstrap any application services.</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'viewPulse'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">User</span> <span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">isAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="自定义" tabindex="-1"><a class="header-anchor" href="#自定义"><span>自定义</span></a></h3>
<p>Pulse 仪表板的卡片和布局可以通过发布仪表板视图进行配置。仪表板视图将发布到 <code v-pre>resources/views/vendor/pulse/dashboard.blade.php</code>：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan vendor:publish <span class="token parameter variable">--tag</span><span class="token operator">=</span>pulse-dashboard</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>该仪表板由 <a href="https://livewire.laravel.com/" target="_blank" rel="noopener noreferrer">Livewire</a> 提供支持，允许你自定义卡片和布局，而无需重新构建任何 JavaScript 资源。</p>
<p>在这个文件中，<code v-pre>&lt;x-pulse&gt;</code> 组件负责渲染仪表板，并为卡片提供网格布局。如果你希望仪表板跨越屏幕的整个宽度，你可以向组件提供 <code v-pre>full-width</code> 属性：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse full-width&gt;</span>
<span class="line">    ...</span>
<span class="line">&lt;/x-pulse&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>默认情况下，<code v-pre>&lt;x-pulse&gt;</code> 组件将创建一个 12 列网格，但你可以使用 <code v-pre>cols</code> 属性进行自定义：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse cols=&quot;16&quot;&gt;</span>
<span class="line">    ...</span>
<span class="line">&lt;/x-pulse&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>每个卡片都接受 <code v-pre>cols</code> 和 <code v-pre>rows</code> 属性来控制空间和定位：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;livewire:pulse.usage cols=&quot;4&quot; rows=&quot;2&quot; /&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>大多数卡片还接受一个 <code v-pre>expand</code> 属性，以显示完整卡片而不是滚动：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;livewire:pulse.slow-queries expand /&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="解决用户" tabindex="-1"><a class="header-anchor" href="#解决用户"><span>解决用户</span></a></h3>
<p>对于显示关于用户信息的卡片，例如应用程序使用情况卡片，Pulse 只会记录用户的 ID。在渲染仪表板时，Pulse 将从你的默认 <code v-pre>Authenticatable</code> 模型中解析 <code v-pre>name</code> 和 <code v-pre>email</code> 字段，并使用 Gravatar 网络服务显示头像。</p>
<p>你可以通过在应用程序的 <code v-pre>App\Providers\AppServiceProvider</code> 类中调用 <code v-pre>Pulse::user</code> 方法来自定义字段和头像。</p>
<p><code v-pre>user</code> 方法接受一个闭包，该闭包将接收要显示的 <code v-pre>Authenticatable</code> 模型，并应返回一个包含用户的 <code v-pre>name</code>、<code v-pre>extra</code> 和 <code v-pre>avatar</code> 信息的数组：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Pulse</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 引导任何应用服务。</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Pulse</span><span class="token operator">::</span><span class="token function">user</span><span class="token punctuation">(</span><span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'extra'</span> <span class="token operator">=></span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">email</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'avatar'</span> <span class="token operator">=></span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">avatar_url</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
通过实现 <code v-pre>Laravel\Pulse\Contracts\ResolvesUsers</code> 合同并在 Laravel 的<a href="https://learnku.com/docs/laravel/11.x/container#binding-a-singleton" target="_blank" rel="noopener noreferrer">服务容器</a>中绑定它，你可以完全自定义如何捕获和检索认证用户。</p>
</blockquote>
<h3 id="卡片" tabindex="-1"><a class="header-anchor" href="#卡片"><span>卡片</span></a></h3>
<h4 id="服务器" tabindex="-1"><a class="header-anchor" href="#服务器"><span>服务器</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.servers /&gt;</code> 卡片显示运行 <code v-pre>pulse:check</code> 命令的所有服务器的系统资源使用情况。有关系统资源报告的更多信息，请参考有关 <a href="#servers-recorder">服务器记录器</a> 的文档。</p>
<p>如果你替换了基础架构中的服务器，你可能希望在给定的持续时间后停止在 Pulse 仪表板中显示非活动服务器。你可以使用 <code v-pre>ignore-after</code> 属性来实现这一点，该属性接受一段时间（秒）后应从 Pulse 仪表板中移除非活动服务器。另外，你也可以提供一个相对时间格式化字符串，比如 <code v-pre>1 小时</code> 或 <code v-pre>3 天 1 小时</code>：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;livewire:pulse.servers ignore-after=&quot;3 小时&quot; /&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="应用程序使用情况" tabindex="-1"><a class="header-anchor" href="#应用程序使用情况"><span>应用程序使用情况</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.usage /&gt;</code> 卡片显示了向您的应用程序发出请求、调度作业以及遇到慢请求的前 10 位用户。</p>
<p>如果你希望同时在屏幕上查看所有使用情况指标，你可以多次包含该卡片并指定 <code v-pre>type</code> 属性：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;livewire:pulse.usage type=&quot;requests&quot; /&gt;</span>
<span class="line">&lt;livewire:pulse.usage type=&quot;slow_requests&quot; /&gt;</span>
<span class="line">&lt;livewire:pulse.usage type=&quot;jobs&quot; /&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>要了解如何自定义 Pulse 检索和显示用户信息的方式，请参阅我们关于<a href="#dashboard-resolving-users">解析用户</a>的文档。</p>
<blockquote>
<p><strong>注意</strong><br>
如果你的应用程序接收大量请求或调度大量作业，你可能希望启用<a href="#sampling">抽样</a>。有关更多信息，请参阅关于<a href="#user-requests-recorder">用户请求记录器</a>、<a href="#user-jobs-recorder">用户作业记录器</a>和<a href="#slow-jobs-recorder">慢作业记录器</a>的文档。</p>
</blockquote>
<h4 id="异常" tabindex="-1"><a class="header-anchor" href="#异常"><span>异常</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.exceptions /&gt;</code> 卡片显示了应用程序中异常发生的频率和最近情况。默认情况下，异常根据异常类和发生位置进行分组。有关更多信息，请参阅<a href="#exceptions-recorder">异常记录器</a>文档。</p>
<h4 id="队列" tabindex="-1"><a class="header-anchor" href="#队列"><span>队列</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.queues /&gt;</code> 卡片显示了应用程序中队列的吞吐量，包括排队、处理、已处理、释放和失败的作业数量。有关更多信息，请参阅<a href="#queues-recorder">队列记录器</a>文档。</p>
<h4 id="慢请求" tabindex="-1"><a class="header-anchor" href="#慢请求"><span>慢请求</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.slow-requests /&gt;</code> 卡片显示了超过配置阈值的传入请求，该阈值默认为 1,000 毫秒。有关更多信息，请参阅<a href="#slow-requests-recorder">慢请求记录器</a>文档。</p>
<h4 id="慢作业" tabindex="-1"><a class="header-anchor" href="#慢作业"><span>慢作业</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.slow-jobs /&gt;</code> 卡片显示了超过配置阈值的应用程序中排队的作业，该阈值默认为 1,000 毫秒。有关更多信息，请参阅<a href="#slow-jobs-recorder">慢作业记录器</a>文档。</p>
<h4 id="慢查询" tabindex="-1"><a class="header-anchor" href="#慢查询"><span>慢查询</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.slow-queries /&gt;</code> 卡片显示了应用程序中超过配置阈值的数据库查询，该阈值默认为 1,000 毫秒。</p>
<p>默认情况下，慢查询根据 SQL 查询（不包括绑定）和发生位置进行分组，但如果你希望仅根据 SQL 查询进行分组，也可以选择不捕获位置。</p>
<p>如果由于接收到非常大的 SQL 查询而遇到渲染性能问题，导致语法高亮显示，你可以通过添加 <code v-pre>without-highlighting</code> 属性来禁用高亮显示：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;livewire:pulse.slow-queries without-highlighting /&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>有关更多信息，请参阅<a href="#slow-queries-recorder">慢查询记录器</a>文档。</p>
<h4 id="慢传出请求" tabindex="-1"><a class="header-anchor" href="#慢传出请求"><span>慢传出请求</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.slow-outgoing-requests /&gt;</code> 卡片显示了使用 Laravel 的<a href="https://learnku.com/docs/laravel/11.x/http-client" target="_blank" rel="noopener noreferrer">HTTP 客户端</a>发出的传出请求，这些请求超过了配置的阈值，默认为 1,000 毫秒。</p>
<p>默认情况下，条目将按照完整 URL 进行分组。但是，你可能希望使用正则表达式对相似的传出请求进行归一化或分组。有关更多信息，请参阅<a href="#slow-outgoing-requests-recorder">慢传出请求记录器</a>文档。</p>
<h4 id="缓存" tabindex="-1"><a class="header-anchor" href="#缓存"><span>缓存</span></a></h4>
<p><code v-pre>&lt;livewire:pulse.cache /&gt;</code> 卡片显示了应用程序的缓存命中和未命中统计信息，包括全局统计和单个键的统计信息。</p>
<p>默认情况下，条目将按键进行分组。但是，你可能希望使用正则表达式对相似的键进行归一化或分组。有关更多信息，请参阅<a href="#cache-interactions-recorder">缓存交互记录器</a>文档。</p>
<h2 id="记录条目" tabindex="-1"><a class="header-anchor" href="#记录条目"><span>记录条目</span></a></h2>
<p>大多数 Pulse 记录器将根据 Laravel 发布的框架事件自动捕获条目。然而，<a href="#servers-recorder">服务器记录器</a>和一些第三方卡片必须定期轮询信息。要使用这些卡片，你必须在所有单独的应用程序服务器上运行 <code v-pre>pulse:check</code> 守护进程：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan pulse<span class="token punctuation">:</span>check</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>[!NOTE]<br>
为了持续在后台运行 <code v-pre>pulse:check</code> 进程，你应该使用诸如 Supervisor 等进程监视器，以确保命令不会停止运行。</p>
</blockquote>
<p>由于 <code v-pre>pulse:check</code> 命令是一个长期运行的进程，它不会在没有重新启动的情况下查看你的代码库更改。你应该在应用程序部署过程中通过调用 <code v-pre>pulse:restart</code> 命令来优雅地重新启动命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan pulse:restart</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
Pulse 使用<a href="https://learnku.com/docs/laravel/11.x/cache" target="_blank" rel="noopener noreferrer">缓存</a>来存储重新启动信号，因此在使用此功能之前，你应该验证为应用程序正确配置了缓存驱动程序。</p>
</blockquote>
<h3 id="记录器" tabindex="-1"><a class="header-anchor" href="#记录器"><span>记录器</span></a></h3>
<p>记录器负责捕获从你的应用程序中记录到 Pulse 数据库中的条目。记录器在<a href="#configuration">Pulse配置文件</a>的<code v-pre>recorders</code>部分中注册和配置。</p>
<h4 id="缓存交互" tabindex="-1"><a class="header-anchor" href="#缓存交互"><span>缓存交互</span></a></h4>
<p><code v-pre>CacheInteractions</code> 记录器捕获有关应用程序中<a href="https://learnku.com/docs/laravel/11.x/cache" target="_blank" rel="noopener noreferrer">缓存</a>命中和未命中的信息，以便在<a href="#cache-card">缓存</a>卡片上显示。</p>
<p>你可以选择调整<a href="#sampling">抽样率</a>和忽略的键模式。</p>
<p>你还可以配置键分组，以便将相似的键作为单个条目分组。例如，你可能希望从缓存相同类型信息的键中删除唯一 ID。组使用正则表达式进行配置，以“查找和替换”键的部分。配置文件中包含一个示例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context">Recorders<span class="token punctuation">\</span>CacheInteractions</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'groups'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token comment">// '/:\d+/' => ':*',</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>第一个匹配的模式将被使用。如果没有模式匹配，则将按原样捕获键。</p>
<h4 id="异常-1" tabindex="-1"><a class="header-anchor" href="#异常-1"><span>异常</span></a></h4>
<p><code v-pre>Exceptions</code> 记录器捕获应用程序中发生的可报告异常的信息，以在<a href="#exceptions-card">异常</a>卡片上显示。</p>
<p>你可以选择调整<a href="#sampling">采样率</a>和忽略的异常模式。你还可以配置是否捕获异常的来源位置。捕获的位置将显示在 Pulse 仪表板上，有助于追踪异常的来源；但是，如果在多个位置发生相同的异常，则对于每个唯一位置，它将多次出现。</p>
<h4 id="队列-1" tabindex="-1"><a class="header-anchor" href="#队列-1"><span>队列</span></a></h4>
<p><code v-pre>Queues</code> 记录器捕获有关你的应用程序队列的信息，以在<a href="#queues-card">队列</a>卡片上显示。</p>
<p>你可以选择调整<a href="#sampling">采样率</a>和忽略的作业模式。</p>
<h4 id="慢作业-1" tabindex="-1"><a class="header-anchor" href="#慢作业-1"><span>慢作业</span></a></h4>
<p><code v-pre>SlowJobs</code> 记录器捕获应用程序中发生的慢作业的信息，以在<a href="#slow-jobs-recorder">慢作业</a>卡片上显示。</p>
<p>你可以选择调整慢作业阈值、<a href="#sampling">采样率</a>和忽略的作业模式。</p>
<p>你可能有一些作业预计会比其他作业花费更长时间。在这种情况下，你可以配置每个作业的阈值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context">Recorders<span class="token punctuation">\</span>SlowJobs</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'threshold'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'#^App\\Jobs\\GenerateYearlyReports$#'</span> <span class="token operator">=></span> <span class="token number">5000</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'default'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'PULSE_SLOW_JOBS_THRESHOLD'</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果没有正则表达式模式与作业的类名匹配，则将使用 <code v-pre>'default'</code> 值。</p>
<h4 id="慢出站请求" tabindex="-1"><a class="header-anchor" href="#慢出站请求"><span>慢出站请求</span></a></h4>
<p><code v-pre>SlowOutgoingRequests</code> 记录器捕获使用 Laravel 的 <a href="https://learnku.com/docs/laravel/11.x/http-client" target="_blank" rel="noopener noreferrer">HTTP 客户端</a> 发出的出站 HTTP 请求的信息，如果超过配置的阈值，则在<a href="#slow-outgoing-requests-card">慢出站请求</a>卡片上显示。</p>
<p>你可以选择调整慢出站请求阈值、<a href="#sampling">采样率</a>和忽略的 URL 模式。</p>
<p>你可能有一些出站请求预计会比其他请求花费更长时间。在这种情况下，你可以配置每个请求的阈值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context">Recorders<span class="token punctuation">\</span>SlowOutgoingRequests</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'threshold'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'#backup.zip$#'</span> <span class="token operator">=></span> <span class="token number">5000</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'default'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'PULSE_SLOW_OUTGOING_REQUESTS_THRESHOLD'</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果没有正则表达式模式与请求的 URL 匹配，则将使用 <code v-pre>'default'</code> 值。</p>
<p>你还可以配置 URL 分组，以便将相似的 URL 作为单个条目进行分组。例如，你可能希望从 URL 路径中删除唯一标识符或仅按域分组。使用正则表达式来配置组，以“查找和替换” URL 的部分。配置文件中包含一些示例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context">Recorders<span class="token punctuation">\</span>SlowOutgoingRequests</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'groups'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token comment">// '#^https://api\.github\.com/repos/.*$#' => 'api.github.com/repos/*',</span></span>
<span class="line">        <span class="token comment">// '#^https?://([^/]*).*$#' => '\1',</span></span>
<span class="line">        <span class="token comment">// '#/\d+#' => '/*',</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>将使用第一个匹配的模式。如果没有模式匹配，则将按原样捕获 URL。</p>
<h4 id="慢查询-1" tabindex="-1"><a class="header-anchor" href="#慢查询-1"><span>慢查询</span></a></h4>
<p><code v-pre>SlowQueries</code> 记录器捕获在你的应用程序中超过配置阈值的任何数据库查询，以在<a href="#slow-queries-card">慢查询</a>卡片上显示。</p>
<p>你可以选择调整慢查询阈值、<a href="#sampling">采样率</a>和忽略的查询模式。你还可以配置是否捕获查询位置。捕获的位置将显示在 Pulse 仪表板上，有助于追踪查询的来源；但是，如果在多个位置进行相同的查询，则对于每个唯一位置，它将多次出现。</p>
<p>你可能有一些查询预计会比其他查询花费更长时间。在这种情况下，你可以配置每个查询的阈值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context">Recorders<span class="token punctuation">\</span>SlowQueries</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'threshold'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'#^insert into `yearly_reports`#'</span> <span class="token operator">=></span> <span class="token number">5000</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'default'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'PULSE_SLOW_QUERIES_THRESHOLD'</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果没有正则表达式模式与查询的 SQL 匹配，则将使用 <code v-pre>'default'</code> 值。</p>
<h4 id="慢请求-1" tabindex="-1"><a class="header-anchor" href="#慢请求-1"><span>慢请求</span></a></h4>
<p><code v-pre>Requests</code> 记录器捕获有关发送到你的应用程序的请求的信息，以在<a href="#slow-requests-card">慢请求</a>和<a href="#application-usage-card">应用程序使用情况</a>卡片上显示。</p>
<p>你可以选择调整慢路由阈值、<a href="#sampling">采样率</a>和忽略的路径。</p>
<p>你可能有一些请求预计会比其他请求花费更长时间。在这种情况下，你可以配置每个请求的阈值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context">Recorders<span class="token punctuation">\</span>SlowRequests</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'threshold'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'#^/admin/#'</span> <span class="token operator">=></span> <span class="token number">5000</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'default'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'PULSE_SLOW_REQUESTS_THRESHOLD'</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果没有正则表达式模式与请求的 URL 匹配，则将使用 <code v-pre>'default'</code> 值。</p>
<h4 id="服务器-1" tabindex="-1"><a class="header-anchor" href="#服务器-1"><span>服务器</span></a></h4>
<p><code v-pre>Servers</code> 记录器捕获用于运行你的应用程序的服务器的 CPU、内存和存储使用情况，以在<a href="#servers-card">服务器</a>卡片上显示。此记录器需要在你希望监视的每台服务器上运行<a href="#capturing-entries"><code v-pre>pulse:check</code>命令</a>。</p>
<p>每个报告服务器必须具有唯一名称。默认情况下，Pulse 将使用 PHP 的 <code v-pre>gethostname</code> 函数返回的值。如果你想自定义此内容，可以设置 <code v-pre>PULSE_SERVER_NAME</code> 环境变量：</p>
<div class="language-env line-numbers-mode" data-highlighter="prismjs" data-ext="env" data-title="env"><pre v-pre class="language-env"><code><span class="line">PULSE_SERVER_NAME=load-balancer</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>Pulse 配置文件还允许你自定义要监视的目录。</p>
<h4 id="用户作业" tabindex="-1"><a class="header-anchor" href="#用户作业"><span>用户作业</span></a></h4>
<p><code v-pre>UserJobs</code> 记录器捕获关于在你的应用程序中调度作业的用户的信息，以在<a href="#application-usage-card">应用程序使用情况</a>卡片上显示。</p>
<p>你可以选择调整<a href="#sampling">采样率</a>和忽略的作业模式。</p>
<h4 id="用户请求" tabindex="-1"><a class="header-anchor" href="#用户请求"><span>用户请求</span></a></h4>
<p><code v-pre>UserRequests</code> 记录器捕获关于向你的应用程序发出请求的用户的信息，以在<a href="#application-usage-card">应用程序使用情况</a>卡片上显示。</p>
<p>你可以选择调整<a href="#sampling">采样率</a>和忽略的作业模式。</p>
<h3 id="过滤" tabindex="-1"><a class="header-anchor" href="#过滤"><span>过滤</span></a></h3>
<p>正如我们所见，许多<a href="#recorders">记录器</a>通过配置提供了根据值（如请求的 URL）“忽略”传入条目的能力。但有时根据其他因素过滤记录可能很有用，比如当前已认证的用户。为了过滤这些记录，你可以将闭包传递给 Pulse 的 <code v-pre>filter</code> 方法。通常，<code v-pre>filter</code> 方法应该在应用程序的 <code v-pre>AppServiceProvider</code> 的 <code v-pre>boot</code> 方法中调用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Auth</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Entry</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Pulse</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Value</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 启动任何应用程序服务。</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Pulse</span><span class="token operator">::</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name">Entry</span><span class="token operator">|</span><span class="token class-name">Value</span> <span class="token variable">$entry</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token class-name static-context">Auth</span><span class="token operator">::</span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">isNotAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="性能" tabindex="-1"><a class="header-anchor" href="#性能"><span>性能</span></a></h2>
<p>Pulse 被设计为可以轻松集成到现有应用程序中，无需额外的基础设施。然而，对于高流量应用程序，有几种方法可以消除 Pulse 对应用程序性能可能产生的影响。</p>
<h3 id="使用不同的数据库" tabindex="-1"><a class="header-anchor" href="#使用不同的数据库"><span>使用不同的数据库</span></a></h3>
<p>对于高流量应用程序，你可能希望为 Pulse 使用一个专用的数据库连接，以避免影响应用程序数据库。</p>
<p>你可以通过设置 <code v-pre>PULSE_DB_CONNECTION</code> 环境变量来自定义 Pulse 使用的<a href="https://learnku.com/docs/laravel/11.x/database#configuration" target="_blank" rel="noopener noreferrer">数据库连接</a>。</p>
<div class="language-env line-numbers-mode" data-highlighter="prismjs" data-ext="env" data-title="env"><pre v-pre class="language-env"><code><span class="line">PULSE_DB_CONNECTION=pulse</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="redis-摄取" tabindex="-1"><a class="header-anchor" href="#redis-摄取"><span>Redis 摄取</span></a></h3>
<blockquote>
<p><strong>警告</strong><br>
Redis 摄取需要 Redis 6.2 或更高版本以及 <code v-pre>phpredis</code> 或 <code v-pre>predis</code> 作为应用程序配置的 Redis 客户端驱动程序。</p>
</blockquote>
<p>默认情况下，Pulse 将在 HTTP 响应发送给客户端后或作业处理完成后，直接将条目存储到<a href="#using-a-different-database">配置的数据库连接</a>中；然而，你可以使用 Pulse 的 Redis 摄取驱动程序将条目发送到 Redis 流中。这可以通过配置 <code v-pre>PULSE_INGEST_DRIVER</code> 环境变量来启用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token constant">PULSE_INGEST_DRIVER</span><span class="token operator">=</span>redis</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>Pulse 默认情况下将使用你的默认<a href="https://learnku.com/docs/laravel/11.x/redis#configuration" target="_blank" rel="noopener noreferrer">Redis连接</a>，但你可以通过 <code v-pre>PULSE_REDIS_CONNECTION</code> 环境变量进行自定义：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token constant">PULSE_REDIS_CONNECTION</span><span class="token operator">=</span>pulse</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>在使用 Redis 摄取时，你需要运行 <code v-pre>pulse:work</code> 命令来监视流并将条目从 Redis 移动到 Pulse 的数据库表中。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan pulse<span class="token punctuation">:</span>work</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
为了在后台持续运行 <code v-pre>pulse:work</code> 进程，你应该使用进程监控器，例如 Supervisor，以确保 Pulse 工作进程不会停止运行。</p>
</blockquote>
<p>由于 <code v-pre>pulse:work</code> 命令是一个长期运行的进程，如果不重新启动，它将无法看到代码库的更改。在应用程序部署过程中，你应该通过调用 <code v-pre>pulse:restart</code> 命令来优雅地重新启动命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan pulse:restart</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
Pulse 使用<a href="https://learnku.com/docs/laravel/11.x/cache" target="_blank" rel="noopener noreferrer">缓存</a>来存储重新启动信号，因此在使用此功能之前，你应该验证为应用程序正确配置了缓存驱动程序。</p>
</blockquote>
<h3 id="采样" tabindex="-1"><a class="header-anchor" href="#采样"><span>采样</span></a></h3>
<p>默认情况下，Pulse 将捕获应用程序中发生的每个相关事件。对于高流量应用程序，这可能导致需要在仪表板中聚合数百万条数据库行，特别是对于较长时间段。</p>
<p>相反，你可以选择在某些 Pulse 数据记录器上启用「采样」。例如，在<a href="#user-requests-recorder"><code v-pre>用户请求</code></a>记录器上将采样率设置为 <code v-pre>0.1</code>，这意味着你只记录大约应用程序请求的 10%。在仪表板中，这些值将被缩放并以 <code v-pre>~</code> 前缀，表示它们是一个近似值。</p>
<p>一般来说，对于特定指标，你拥有的条目越多，你就可以将采样率设置得越低，而不会牺牲太多准确性。</p>
<h3 id="裁剪" tabindex="-1"><a class="header-anchor" href="#裁剪"><span>裁剪</span></a></h3>
<p>一旦超出仪表板窗口范围，Pulse 将自动裁剪其存储的条目。裁剪发生在使用抽奖系统进行数据摄取时，这可以在 Pulse 的<a href="#configuration">配置文件</a>中进行自定义。</p>
<h3 id="处理-pulse-异常" tabindex="-1"><a class="header-anchor" href="#处理-pulse-异常"><span>处理 Pulse 异常</span></a></h3>
<p>如果在捕获 Pulse 数据时发生异常，例如无法连接到存储数据库，Pulse 将会静默失败，以避免影响你的应用程序。</p>
<p>如果你希望自定义如何处理这些异常，你可以为 <code v-pre>handleExceptionsUsing</code> 方法提供一个闭包：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Pulse</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Log</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Pulse</span><span class="token operator">::</span><span class="token function">handleExceptionsUsing</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Pulse 中发生了异常'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'message'</span> <span class="token operator">=></span> <span class="token variable">$e</span><span class="token operator">-></span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'stack'</span> <span class="token operator">=></span> <span class="token variable">$e</span><span class="token operator">-></span><span class="token function">getTraceAsString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="自定义卡片" tabindex="-1"><a class="header-anchor" href="#自定义卡片"><span>自定义卡片</span></a></h2>
<p>Pulse 允许你构建自定义卡片，以显示与你的应用程序特定需求相关的数据。Pulse 使用 <a href="https://livewire.laravel.com/" target="_blank" rel="noopener noreferrer">Livewire</a>，因此在构建第一个自定义卡片之前，你可能需要<a href="https://livewire.laravel.com/docs" target="_blank" rel="noopener noreferrer">查阅其文档</a>。</p>
<h3 id="卡片组件" tabindex="-1"><a class="header-anchor" href="#卡片组件"><span>卡片组件</span></a></h3>
<p>在 Laravel Pulse 中创建自定义卡片始于扩展基本的 <code v-pre>Card</code> Livewire 组件并定义相应的视图：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Livewire<span class="token punctuation">\</span>Pulse</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Livewire<span class="token punctuation">\</span>Card</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Livewire<span class="token punctuation">\</span>Attributes<span class="token punctuation">\</span>Lazy</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token attribute"><span class="token delimiter punctuation">#[</span><span class="token attribute-content"><span class="token attribute-class-name class-name">Lazy</span></span><span class="token delimiter punctuation">]</span></span></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">TopSellers</span> <span class="token keyword">extends</span> <span class="token class-name">Card</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'livewire.pulse.top-sellers'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当使用 Livewire 的<a href="https://livewire.laravel.com/docs/lazy" target="_blank" rel="noopener noreferrer">延迟加载</a>功能时，<code v-pre>Card</code> 组件将自动提供一个占位符，以符合传递给你的组件的 <code v-pre>cols</code> 和 <code v-pre>rows</code> 属性。</p>
<p>在编写 Pulse 卡片的相应视图时，你可以利用 Pulse 的 Blade 组件以获得一致的外观和感觉：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse::card :cols=&quot;$cols&quot; :rows=&quot;$rows&quot; :class=&quot;$class&quot; wire:poll.5s=&quot;&quot;&gt;</span>
<span class="line">    &lt;x-pulse::card-header name=&quot;Top Sellers&quot;&gt;</span>
<span class="line">        &lt;x-slot:icon&gt;</span>
<span class="line">            ...</span>
<span class="line">        &lt;/x-slot:icon&gt;</span>
<span class="line">    &lt;/x-pulse::card-header&gt;</span>
<span class="line"></span>
<span class="line">    &lt;x-pulse::scroll :expand=&quot;$expand&quot;&gt;</span>
<span class="line">        ...</span>
<span class="line">    &lt;/x-pulse::scroll&gt;</span>
<span class="line">&lt;/x-pulse::card&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>应将 <code v-pre>$cols</code>、<code v-pre>$rows</code>、<code v-pre>$class</code> 和 <code v-pre>$expand</code> 变量传递给各自的 Blade 组件，以便从仪表板视图自定义卡片布局。你还可以在视图中包含 <code v-pre>wire:poll.5s=&quot;&quot;</code> 属性，以使卡片自动更新。</p>
<p>一旦你定义了 Livewire 组件和模板，该卡片就可以包含在你的<a href="#dashboard-customization">仪表板视图</a>中：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse&gt;</span>
<span class="line">    ...</span>
<span class="line"></span>
<span class="line">    &lt;livewire:pulse.top-sellers cols=&quot;4&quot; /&gt;</span>
<span class="line">&lt;/x-pulse&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
如果你的卡片包含在一个软件包中，你需要使用 <code v-pre>Livewire::component</code> 方法向 Livewire 注册组件。</p>
</blockquote>
<h3 id="样式" tabindex="-1"><a class="header-anchor" href="#样式"><span>样式</span></a></h3>
<p>如果你的卡片需要超出 Pulse 包含的类和组件的额外样式，有几种选项可用于为你的卡片包含自定义 CSS。</p>
<h4 id="laravel-vite-集成" tabindex="-1"><a class="header-anchor" href="#laravel-vite-集成"><span>Laravel Vite 集成</span></a></h4>
<p>如果你的自定义卡片位于应用程序的代码库中，并且你正在使用 Laravel 的<a href="https://learnku.com/docs/laravel/11.x/vite" target="_blank" rel="noopener noreferrer">Vite集成</a>，你可以更新你的 <code v-pre>vite.config.js</code> 文件，包含一个专门的 CSS 入口点用于你的卡片：</p>
<div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js" data-title="js"><pre v-pre class="language-javascript"><code><span class="line"><span class="token function">laravel</span><span class="token punctuation">(</span><span class="token punctuation">{</span></span>
<span class="line">    <span class="token literal-property property">input</span><span class="token operator">:</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string">'resources/css/pulse/top-sellers.css'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>然后，在<a href="#dashboard-customization">仪表板视图</a>中使用 <code v-pre>@vite</code> Blade 指令，指定你的卡片的 CSS 入口点：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse&gt;</span>
<span class="line">    @vite('resources/css/pulse/top-sellers.css')</span>
<span class="line"></span>
<span class="line">    ...</span>
<span class="line">&lt;/x-pulse&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="css-文件" tabindex="-1"><a class="header-anchor" href="#css-文件"><span>CSS 文件</span></a></h4>
<p>对于其他用例，包括包含在软件包中的 Pulse 卡片，你可以通过在 Livewire 组件上定义一个返回 CSS 文件路径的 <code v-pre>css</code> 方法，指示 Pulse 加载额外的样式表：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">TopSellers</span> <span class="token keyword">extends</span> <span class="token class-name">Card</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">css</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token constant">__DIR__</span><span class="token operator">.</span><span class="token string single-quoted-string">'/../../dist/top-sellers.css'</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当这个卡片包含在仪表板上时，Pulse 将自动在 <code v-pre>&lt;style&gt;</code> 标签中包含此文件的内容，因此无需将其发布到 <code v-pre>public</code> 目录中。</p>
<h4 id="tailwind-css" tabindex="-1"><a class="header-anchor" href="#tailwind-css"><span>Tailwind CSS</span></a></h4>
<p>使用 Tailwind CSS 时，你应该创建一个专门的 Tailwind 配置文件，以避免加载不必要的 CSS 或与 Pulse 的 Tailwind 类冲突：</p>
<div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js" data-title="js"><pre v-pre class="language-javascript"><code><span class="line"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token literal-property property">darkMode</span><span class="token operator">:</span> <span class="token string">'class'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token literal-property property">important</span><span class="token operator">:</span> <span class="token string">'#top-sellers'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token literal-property property">content</span><span class="token operator">:</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string">'./resources/views/livewire/pulse/top-sellers.blade.php'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token literal-property property">corePlugins</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token literal-property property">preflight</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>然后，在你的 CSS 入口点中指定配置文件：</p>
<div class="language-css line-numbers-mode" data-highlighter="prismjs" data-ext="css" data-title="css"><pre v-pre class="language-css"><code><span class="line"><span class="token atrule"><span class="token rule">@config</span> <span class="token string">"../../tailwind.top-sellers.config.js"</span><span class="token punctuation">;</span></span></span>
<span class="line"><span class="token atrule"><span class="token rule">@tailwind</span> base<span class="token punctuation">;</span></span></span>
<span class="line"><span class="token atrule"><span class="token rule">@tailwind</span> components<span class="token punctuation">;</span></span></span>
<span class="line"><span class="token atrule"><span class="token rule">@tailwind</span> utilities<span class="token punctuation">;</span></span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还需要在卡片的视图中包含一个与传递给 Tailwind 的<a href="https://tailwindcss.com/docs/configuration#selector-strategy" target="_blank" rel="noopener noreferrer"><code v-pre>important</code>选择器策略</a>匹配的 <code v-pre>id</code> 或 <code v-pre>class</code> 属性：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse::card id=&quot;top-sellers&quot; :cols=&quot;$cols&quot; :rows=&quot;$rows&quot; class=&quot;$class&quot;&gt;</span>
<span class="line">    ...</span>
<span class="line">&lt;/x-pulse::card&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="数据捕获和聚合" tabindex="-1"><a class="header-anchor" href="#数据捕获和聚合"><span>数据捕获和聚合</span></a></h3>
<p>自定义卡片可以从任何地方获取和显示数据；然而，你可能希望利用 Pulse 强大而高效的数据记录和聚合系统。</p>
<h4 id="捕获条目" tabindex="-1"><a class="header-anchor" href="#捕获条目"><span>捕获条目</span></a></h4>
<p>Pulse 允许你使用 <code v-pre>Pulse::record</code> 方法记录 &quot;条目&quot;：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Pulse</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Pulse</span><span class="token operator">::</span><span class="token function">record</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user_sale'</span><span class="token punctuation">,</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span> <span class="token variable">$sale</span><span class="token operator">-></span><span class="token property">amount</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>提供给 <code v-pre>record</code> 方法的第一个参数是你要记录的条目的 <code v-pre>type</code>，而第二个参数是确定如何分组聚合数据的 <code v-pre>key</code>。对于大多数聚合方法，你还需要指定要聚合的 <code v-pre>value</code>。在上面的示例中，要聚合的值是 <code v-pre>$sale-&gt;amount</code>。然后，你可以调用一个或多个聚合方法（例如 <code v-pre>sum</code>），以便 Pulse 可以捕获预先聚合的值到 &quot;存储桶&quot; 中，以便稍后高效地检索。</p>
<p>可用的聚合方法有：</p>
<ul>
<li><code v-pre>avg</code></li>
<li><code v-pre>count</code></li>
<li><code v-pre>max</code></li>
<li><code v-pre>min</code></li>
<li><code v-pre>sum</code></li>
</ul>
<blockquote>
<p><strong>注意</strong><br>
当构建一个捕获当前认证用户 ID 的卡片包时，你应该使用 <code v-pre>Pulse::resolveAuthenticatedUserId()</code> 方法，该方法尊重应用程序中进行的任何<a href="#dashboard-resolving-users">用户解析器自定义</a>。</p>
</blockquote>
<h4 id="检索聚合数据" tabindex="-1"><a class="header-anchor" href="#检索聚合数据"><span>检索聚合数据</span></a></h4>
<p>当扩展 Pulse 的 <code v-pre>Card</code> Livewire 组件时，你可以使用 <code v-pre>aggregate</code> 方法来检索在仪表板中查看的期间的聚合数据：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">TopSellers</span> <span class="token keyword">extends</span> <span class="token class-name">Card</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'livewire.pulse.top-sellers'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'topSellers'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">aggregate</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user_sale'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'sum'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'count'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>aggregate</code> 方法返回一个 PHP <code v-pre>stdClass</code> 对象的集合。每个对象将包含之前捕获的 <code v-pre>key</code> 属性，以及每个请求的聚合的键：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">@<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$topSellers</span> <span class="token keyword">as</span> <span class="token variable">$seller</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">$seller</span><span class="token operator">-></span><span class="token property">key</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">$seller</span><span class="token operator">-></span><span class="token property">sum</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">$seller</span><span class="token operator">-></span><span class="token property">count</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
<span class="line">@<span class="token keyword">endforeach</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Pulse 主要会从预先聚合的存储桶中检索数据；因此，指定的聚合必须事先使用 <code v-pre>Pulse::record</code> 方法捕获。最老的存储桶通常会部分地超出该期间，因此 Pulse 将聚合最老的条目以填补间隙，并为整个期间提供准确的值，而无需在每次轮询请求中聚合整个期间。</p>
<p>你也可以通过使用 <code v-pre>aggregateTotal</code> 方法来检索给定类型的总值。例如，以下方法将检索所有用户销售的总和，而不是按用户分组。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$total</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">aggregateTotal</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user_sale'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'sum'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="显示用户" tabindex="-1"><a class="header-anchor" href="#显示用户"><span>显示用户</span></a></h4>
<p>当使用记录用户 ID 作为键的聚合时，你可以使用 <code v-pre>Pulse::resolveUsers</code> 方法将键解析为用户记录：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$aggregates</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">aggregate</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user_sale'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'sum'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'count'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token class-name static-context">Pulse</span><span class="token operator">::</span><span class="token function">resolveUsers</span><span class="token punctuation">(</span><span class="token variable">$aggregates</span><span class="token operator">-></span><span class="token function">pluck</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'livewire.pulse.top-sellers'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'sellers'</span> <span class="token operator">=></span> <span class="token variable">$aggregates</span><span class="token operator">-></span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">fn</span> <span class="token punctuation">(</span><span class="token variable">$aggregate</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token keyword type-casting">object</span><span class="token punctuation">)</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'user'</span> <span class="token operator">=></span> <span class="token variable">$users</span><span class="token operator">-></span><span class="token function">find</span><span class="token punctuation">(</span><span class="token variable">$aggregate</span><span class="token operator">-></span><span class="token property">key</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'sum'</span> <span class="token operator">=></span> <span class="token variable">$aggregate</span><span class="token operator">-></span><span class="token property">sum</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'count'</span> <span class="token operator">=></span> <span class="token variable">$aggregate</span><span class="token operator">-></span><span class="token property">count</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>find</code> 方法返回一个包含 <code v-pre>name</code>、<code v-pre>extra</code> 和 <code v-pre>avatar</code> 键的对象，你可以选择直接将其传递给 <code v-pre>&lt;x-pulse::user-card&gt;</code> Blade 组件：</p>
<div class="language-blade line-numbers-mode" data-highlighter="prismjs" data-ext="blade" data-title="blade"><pre v-pre class="language-blade"><code><span class="line">&lt;x-pulse::user-card :user=&quot;{{ $seller-&gt;user }}&quot; :stats=&quot;{{ $seller-&gt;sum }}&quot; /&gt;</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="自定义记录器" tabindex="-1"><a class="header-anchor" href="#自定义记录器"><span>自定义记录器</span></a></h4>
<p>包作者可能希望提供记录器类，以允许用户配置数据的捕获。</p>
<p>记录器在应用程序的 <code v-pre>config/pulse.php</code> 配置文件的 <code v-pre>recorders</code> 部分中注册：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'recorders'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name class-name-fully-qualified static-context">Acme<span class="token punctuation">\</span>Recorders<span class="token punctuation">\</span>Deployments</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token comment">// ...</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>记录器可以通过指定 <code v-pre>$listen</code> 属性来监听事件。Pulse 将自动注册监听器并调用记录器的 <code v-pre>record</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">Acme<span class="token punctuation">\</span>Recorders</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Acme<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>Deployment</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Config</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Pulse<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Pulse</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Deployments</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 要监听的事件。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">array</span></span>&lt;int, class-string></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword type-declaration">array</span> <span class="token variable">$listen</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">Deployment</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 记录部署。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">record</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Deployment</span> <span class="token variable">$event</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$config</span> <span class="token operator">=</span> <span class="token class-name static-context">Config</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'pulse.recorders.'</span><span class="token operator">.</span><span class="token keyword static-context">static</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token class-name static-context">Pulse</span><span class="token operator">::</span><span class="token function">record</span><span class="token punctuation">(</span></span>
<span class="line">            <span class="token comment">// ...</span></span>
<span class="line">        <span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/11.x/pulsemd/16729" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/pu...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/11.x/pulsemd/16729" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/pu...</a></p>
</blockquote>
</div></template>


